package com.pubinfo.passbook.data.config;

import cn.hutool.core.codec.Base64;
import com.pubinfo.passbook.shiro.filter.MyPassThruAuthenticationFilter;
import com.pubinfo.passbook.shiro.realm.CustomRealm;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.BeansException;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.filter.DelegatingFilterProxy;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
@Slf4j
public class ShiroConfig implements ApplicationContextAware {
  
  private static ApplicationContext context = null;
  
  @Override
  public void setApplicationContext(ApplicationContext applicationContext)
      throws BeansException {
    context = applicationContext;
  }
  
  /// 获取当前环境
  public String getActiveProfile() {
    return context.getEnvironment().getActiveProfiles()[0];
  }
  
  //  @Bean
//  public DefaultWebSessionManager newSessionManager() {
//    DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//    sessionManager.setSessionValidationSchedulerEnabled(true);
//    sessionManager.setSessionIdUrlRewritingEnabled(false);
//    sessionManager.setSessionValidationInterval(3600 * 1000);
//    sessionManager.setGlobalSessionTimeout(3600 * 1000);
//    return sessionManager;
//  }
  @Bean
  public DefaultWebSessionManager newSessionManager() {
    MySessionManager sessionManager = new MySessionManager();
    sessionManager.setSessionValidationSchedulerEnabled(true);
    sessionManager.setSessionIdUrlRewritingEnabled(false);
    sessionManager.setSessionValidationInterval(3600 * 1000);
    sessionManager.setGlobalSessionTimeout(3600 * 1000);
    return sessionManager;
  }
  
  @Bean
  public FilterRegistrationBean shiroFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new DelegatingFilterProxy("shiroFilter"));
    //该值缺省为false，表示生命周期由SpringApplicationContext管理，设置为true则表示由ServletContainer管理
    //registration.addInitParameter("targetFilterLifecycle", "true");
    
    registration.setEnabled(true);
    registration.setOrder(Integer.MAX_VALUE - 1);
    registration.addUrlPatterns("/*");
    return registration;
  }
  
  /**
   * 注入securityManager安全管理器
   *
   * @param customRealm
   * @return
   */
  
  @Bean("securityManager")
  public DefaultWebSecurityManager newSecurityManager(CustomRealm customRealm) {
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    securityManager.setRealm(customRealm);
    securityManager.setSessionManager(newSessionManager());
    securityManager.setRememberMeManager(newRememberMeManager());
    securityManager.setCacheManager(newCacheManager());
    return securityManager;
  }
  
  public RememberMeManager newRememberMeManager() {
    CookieRememberMeManager cManager = new CookieRememberMeManager();
    cManager.setCookie(newCookie());
    cManager.setCipherKey(Base64.decode("6ZmI6I2j5Y+R5aSn5ZOlAA=="));
    return cManager;
  }
  
  public SimpleCookie newCookie() {
    SimpleCookie sc = new SimpleCookie("rememberMe");
    sc.setMaxAge(7 * 24 * 60 * 60);
    return sc;
  }
  
  public CacheManager newCacheManager() {
    MemoryConstrainedCacheManager cacheManager = new MemoryConstrainedCacheManager();
    return cacheManager;
  }
  
  @Bean("shiroFilter")
  public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
    ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
    
    //添加自己的过滤器
    Map<String, Filter> filterMap = new LinkedHashMap<>();
    // filterMap.put("authc", new ShiroHeaderFilter());
    //  filterMap.put("roles",new ShiroRolesAuthorizationFilter());
    //  filterMap.put("jwt", new MyJWTFilter());
    // filterMap.put("authc", new MyShiroFilter());
    filterMap.put("userFilter", new MyPassThruAuthenticationFilter());
    
    factoryBean.setFilters(filterMap);
    factoryBean.setSecurityManager(securityManager);
    // factoryBean.setLoginUrl("/user/doLoginUI");
    // factoryBean.setUnauthorizedUrl("/");
    //设置未登录的跳转的url
    factoryBean.setUnauthorizedUrl("http://134.96.180.52:8088/cas/login");
    factoryBean.setLoginUrl("http://134.96.180.52:8088/cas/login");
    //设置拦截器
    LinkedHashMap<String, String> filterRuleMap = new LinkedHashMap<>();
    //开发接口
    //filterRuleMap.put("/", "anon");
    //开发阶段,放开全部
    // filterRuleMap.put("/**", "anon");
    //其余接口一律拦截
    // filterRuleMap.put("/**", "myShiroFilter");
    String active = getActiveProfile();
    if ("test,dev".contains(active)) {
    }
  
    filterRuleMap.put("/file/acctDownloadZip", "anon");
    filterRuleMap.put("/file/acctDownload/*", "anon");
    filterRuleMap.put("/file/uploadArtificialFile", "anon");
    filterRuleMap.put("/file/uploadFile", "anon");
    filterRuleMap.put("/file/saveTFileEnclosure", "anon");
    filterRuleMap.put("/Artifical/*", "anon");
    filterRuleMap.put("/FeedbackFile/*", "anon");
    filterRuleMap.put("/druid/*", "anon");
  
    filterRuleMap.put("/open/**", "anon");
    filterRuleMap.put("/mss/**", "anon");
    filterRuleMap.put("/task/**", "anon");
    filterRuleMap.put("/passbook/**", "anon");
    filterRuleMap.put("/com/pubinfo/passbook/**", "anon");
    filterRuleMap.put("/swagger-resources/**", "anon");
    filterRuleMap.put("/com/pubinfo/passbook/detailsByParam", "anon");
    filterRuleMap.put("/swagger**", "anon");
    filterRuleMap.put("/doc.html", "anon");
    filterRuleMap.put("/test/**", "anon");
    filterRuleMap.put("/webjars/**", "anon");
    filterRuleMap.put("/v2/**", "anon");
    // filterRuleMap.put("/**", "authc");
    
    //filterRuleMap.put("/**", "jwt");
    filterRuleMap.put("/template/**", "anon");
    filterRuleMap.put("/websocket/**", "anon");
    filterRuleMap.put("/user/login", "anon");
    filterRuleMap.put("/csrf**", "anon");
    filterRuleMap.put("/**", "userFilter");
    filterRuleMap.put("/favicon.ico", "anon");
    
    factoryBean.setFilterChainDefinitionMap(filterRuleMap);
    return factoryBean;
  }
  
  @Bean("lifecycleBeanPostProcessor")
  public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
  }
  
  @Bean
  @DependsOn("lifecycleBeanPostProcessor")
  public DefaultAdvisorAutoProxyCreator newProxyCreator() {
    return new DefaultAdvisorAutoProxyCreator();
  }
  
  @Bean
  public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
    advisor.setSecurityManager(securityManager);
    return advisor;
  }
  
}
